package cc.rengu.igas.bomp.core.model;

import cc.rengu.igas.bomp.common.constant.BompAppParamConstant;
import cc.rengu.igas.bomp.common.constant.DubboMethodConstant;
import cc.rengu.igas.bomp.common.constant.TableNameConstant;
import cc.rengu.igas.bomp.common.dao.AlipayMchntInfoMapper;
import cc.rengu.igas.bomp.common.dao.BizHistoryMapper;
import cc.rengu.igas.bomp.common.dao.MchntAcctInfoMapper;
import cc.rengu.igas.bomp.common.dao.impl.AlipayMchntInfoMapperImpl;
import cc.rengu.igas.bomp.common.dao.impl.BizHistoryMapperImpl;
import cc.rengu.igas.bomp.common.dao.impl.MchntAcctInfoMapperImpl;
import cc.rengu.igas.bomp.common.entity.*;
import cc.rengu.igas.bomp.common.enums.RespCodeEnum;
import cc.rengu.igas.bomp.common.util.ChangeNextStatusUtil;
import cc.rengu.igas.bomp.common.util.InitParamUtil;
import cc.rengu.igas.channel.alipay.facade.bean.AddressInfo;
import cc.rengu.igas.channel.alipay.facade.bean.BankCardInfo;
import cc.rengu.igas.channel.alipay.facade.bean.ContactInfo;
import cc.rengu.igas.channel.alipay.facade.request.AliCreateMerchantRequest;
import cc.rengu.igas.channel.alipay.facade.request.AliUpdateMerchantRequest;
import cc.rengu.igas.channel.alipay.facade.response.AliCreateMerchantResponse;
import cc.rengu.igas.channel.alipay.facade.response.AliUpdateMerchantResponse;
import cc.rengu.igas.channel.alipay.facade.result.Result;
import cc.rengu.oltp.service.common.constant.AppConfigConstant;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.entity.ChannelCallCfg;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.TxnInfo;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.utility.util.*;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;
import com.alibaba.fastjson.JSONObject;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class AlipayIntegration {

    private final RgLogger rglog = RgLog.getLogger(this.getClass().getName());

    public boolean createMerchant(AlipayMchntInfo alipayMchntInfo, String sysSeqNum, MchntBaseInfo mchntBaseInfo, MchntSignInfo mchntSignInfo, TxnInfo txnInfo) {
        boolean result = true;

        try {
            //支付宝进件
            if (null != alipayMchntInfo && StringUtil.isEmptyOrNull(alipayMchntInfo.getAlipayMchntNo())) {
                //判断当前状态是否允许修改
                if (!ChangeNextStatusUtil.isAllowModifyData(alipayMchntInfo.getAuditStatus())) {
                    rglog.error("支付宝商户进件处理失败, 当前支付宝商户信息待审核，不允许进行进件操作，instId:{},mchntNo:{},当前商户审核状态:{}",
                            alipayMchntInfo.getInstId(), alipayMchntInfo.getMchntNo(), alipayMchntInfo.getAuditStatus());
                    throw new BizException(RespCodeEnum.MANAGE_OPERATE_ERROR.getRespCode(), RespCodeEnum.MANAGE_OPERATE_ERROR.getRespDesc());
                }

                //获取通道服务调用配置- 支付宝
                //获取通道服务调用配置-微信
                List<ChannelCallCfg> channelCallCfgList = txnInfo.getChannelCallCfgList().stream().filter(item -> item.getCallChannelId().equals(ChannelEnum.UPAL.getChannelType()) ||
                        item.getCallChannelId().equals(ChannelEnum.NUAL.getChannelType()) || item.getCallChannelId().equals(ChannelEnum.ALIP.getChannelType())).sorted(Comparator.comparing(ChannelCallCfg::getCallIndex)).collect(Collectors.toList());
                ChannelCallCfg aliChannelCallCfg = channelCallCfgList.get(0);
                if (ChannelEnum.ALIP.getChannelType().equals(aliChannelCallCfg.getCallChannelId())) {
                    rglog.info("直联支付宝进件需要先获取商户应用授权，请在内管平台上点击支付宝进件按钮完成博时进件申请!");
                    return result;
                }

                //调用支付宝进行商户入驻
                AliCreateMerchantRequest aliCreateMerchantRequest = initAliCreateMerchantRequest(sysSeqNum, mchntBaseInfo, alipayMchntInfo, mchntSignInfo, aliChannelCallCfg);
                DubboService dubboService = new DubboServiceImpl();
                Object object = dubboService.callDubboService(DubboMethodConstant.DUBBO_ALIPAY_MCHNT_SERVICE, "aliCreateMerchant", aliCreateMerchantRequest);
                cc.rengu.igas.channel.alipay.facade.result.Result<AliCreateMerchantResponse> aliResult = (Result<AliCreateMerchantResponse>) object;
                if (null != aliResult && aliResult.isSuccess() && DubboMethodConstant.DUBBO_SUCCESS.equals(aliResult.getResult().getRespCode())) {
                    //更新商户支付宝信息表与历史数据表 入驻成功
                    alipayMchntInfo.setAlipayMchntNo(aliResult.getResult().getAliMchntNo());
                    alipayMchntInfo.setAlipayEntryFlag("01");
                    BizHistory bizHistory = new BizHistory();
                    BeanUtil.beanCopy(alipayMchntInfo, bizHistory);
                    bizHistory.setManageInstId(mchntBaseInfo.getSignInstId());
                    bizHistory.setMchntName(mchntBaseInfo.getMchntName());
                    bizHistory.setRealId(alipayMchntInfo.getId());
                    bizHistory.setOprTableEname(TableNameConstant.T_B_ALPAY_MCHNT_INFO);
                    //修改
                    bizHistory.setBizOpr("U");
                    String modifyAliMchntInfoJson = JSONObject.toJSONString(alipayMchntInfo);

                    //将正式表的商户信息存入历史表 bizData
                    InitParamUtil.initBizHistoryData(bizHistory, modifyAliMchntInfoJson);
                    modifyAliMchntInfoData(alipayMchntInfo, bizHistory);
                } else {
                    rglog.error("支付宝商户进件处理失败, 当前支付宝商户信息进件失败，instId:{},mchntNo:{},当前商户审核状态:{}",
                            alipayMchntInfo.getInstId(), alipayMchntInfo.getMchntNo(), alipayMchntInfo.getAuditStatus());
                    //更新商户支付宝信息表与历史数据表 入驻失败
                    alipayMchntInfo.setAlipayEntryFlag("02");
                    BizHistory bizHistory = new BizHistory();
                    BeanUtil.beanCopy(alipayMchntInfo, bizHistory);
                    bizHistory.setManageInstId(mchntBaseInfo.getSignInstId());
                    bizHistory.setMchntName(mchntBaseInfo.getMchntName());
                    bizHistory.setRealId(alipayMchntInfo.getId());
                    bizHistory.setOprTableEname(TableNameConstant.T_B_ALPAY_MCHNT_INFO);
                    //修改
                    bizHistory.setBizOpr("U");
                    String modifyAliMchntInfoJson = JSONObject.toJSONString(alipayMchntInfo);

                    //将正式表的商户信息存入历史表 bizData
                    InitParamUtil.initBizHistoryData(bizHistory, modifyAliMchntInfoJson);
                    modifyAliMchntInfoData(alipayMchntInfo, bizHistory);
                    result = false;
                }
            } else if (null != alipayMchntInfo) {
                List<ChannelCallCfg> channelCallCfgList = txnInfo.getChannelCallCfgList().stream().filter(item -> item.getCallChannelId().equals(ChannelEnum.UPAL.getChannelType()) ||
                        item.getCallChannelId().equals(ChannelEnum.NUAL.getChannelType()) || item.getCallChannelId().equals(ChannelEnum.ALIP.getChannelType())).sorted(Comparator.comparing(ChannelCallCfg::getCallIndex)).collect(Collectors.toList());
                ChannelCallCfg aliChannelCallCfg = channelCallCfgList.get(1);

                //调用支付宝进行商户修改
                AliCreateMerchantRequest aliCreateMerchantRequest = initAliCreateMerchantRequest(sysSeqNum, mchntBaseInfo, alipayMchntInfo, mchntSignInfo, aliChannelCallCfg);
                AliUpdateMerchantRequest aliUpdateMerchantRequest = new AliUpdateMerchantRequest();
                //数据一致
                BeanUtil.beanCopy(aliCreateMerchantRequest, aliUpdateMerchantRequest);
                aliUpdateMerchantRequest.setHeader(aliCreateMerchantRequest.getHeader());
                DubboService dubboService = new DubboServiceImpl();
                Object object = dubboService.callDubboService(DubboMethodConstant.DUBBO_ALIPAY_MCHNT_SERVICE, "aliUpdateMerchant", aliUpdateMerchantRequest);
                cc.rengu.igas.channel.alipay.facade.result.Result<AliUpdateMerchantResponse> aliResult = (Result<AliUpdateMerchantResponse>) object;
                if (null == aliResult || !aliResult.isSuccess() || !DubboMethodConstant.DUBBO_SUCCESS.equals(aliResult.getResult().getRespCode())) {
                    result = false;
                    rglog.error("支付宝商户更新商户信息失败,instId:{},mchntNo:{}", alipayMchntInfo.getInstId(), alipayMchntInfo.getMchntNo());
                }

            }
        } catch (Exception e) {
            result = false;
            rglog.error("支付宝商户信息新增或修改失败，instId:{},mchntNo:{}, 异常原因:{}",
                    alipayMchntInfo.getInstId(), alipayMchntInfo.getMchntNo(), e.getMessage());
        }

        return result;
    }

    private void modifyAliMchntInfoData(AlipayMchntInfo alipayMchntInfo, BizHistory bizHistory) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        /* 开启数据库事务 */
        String dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(AppConfigConstant.DATABASE_CONF_NODE, AppConfigConstant.MCMP_POOL_NAME);
        String corporation = xmlTreeUtil.getXmlTreeStringValue(AppParamConstant.CORPORATION);
        if (null != corporation && !corporation.isEmpty()) {
            String dbPoolCashNode = corporation.trim() + AppParamConstant.DATABASE_CONF_NODE;
            dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(dbPoolCashNode, AppConfigConstant.MCMP_POOL_NAME);
        }
        DbsUtil dbsUtil = new DbsUtil(dbPoolName);
        dbsUtil.dbsBeginTransaction();

        AlipayMchntInfoMapper alipayMchntInfoMapper = new AlipayMchntInfoMapperImpl();
        int dbResult = alipayMchntInfoMapper.updateAlipayMchntInfoById(alipayMchntInfo);
        if (dbResult != 0) {
            dbsUtil.dbsEndTransaction(false);
            rglog.error("支付宝商户进件-修改支付宝商户信息表失败！id:{},mchnt:{},instId:{}",
                    alipayMchntInfo.getId(), alipayMchntInfo.getMchntNo(), alipayMchntInfo.getInstId());
            throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
        }

        if (null != bizHistory) {
            bizHistory.setCreateTime(DateUtil.getCurrentDateTime(InitParamUtil.yyyy_MM_dd_HHmmssSSS));
            BizHistoryMapper bizHistoryMapper = new BizHistoryMapperImpl();
            dbResult = bizHistoryMapper.insertBompBizHistory(bizHistory);
            if (dbResult != 0) {
                dbsUtil.dbsEndTransaction(false);
                rglog.error("支付宝商户进件-新增业务历史表记录失败！realId:{},manageInstId:{},instId:{}",
                        bizHistory.getRealId(), bizHistory.getManageInstId(), bizHistory.getInstId());
                throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
            }
        }

        dbsUtil.dbsEndTransaction(true);
    }

    private AliCreateMerchantRequest initAliCreateMerchantRequest(String sysSeqNum,
                                                                  MchntBaseInfo mchntBaseInfo,
                                                                  AlipayMchntInfo alipayMchntInfo,
                                                                  MchntSignInfo mchntSignInfo,
                                                                  ChannelCallCfg channelCallCfg) throws Exception {

        MchntAcctInfoMapper mchntAcctInfoMapper = new MchntAcctInfoMapperImpl();
        List<MchntAcctInfo> mchntAcctInfoList = mchntAcctInfoMapper.selectMchntAcctInfoByMchntNo(mchntBaseInfo.getInstId(), mchntBaseInfo.getMchntNo());


        AliCreateMerchantRequest aliCreateMerchantRequest = new AliCreateMerchantRequest();
        cc.rengu.igas.channel.alipay.facade.base.Header header = new cc.rengu.igas.channel.alipay.facade.base.Header();
        BeanUtil.beanCopy(alipayMchntInfo, aliCreateMerchantRequest);
        header.setInstId(alipayMchntInfo.getInstId());
        header.setChanlId(ChannelEnum.BOMP.getChannelType());
        header.setSrcSysId(AppParamConstant.SYS_ID);
        header.setTxnNum(channelCallCfg.getCallChannelTxn());
        header.setVersion("1.0.0");
        String channelSeqNum = sysSeqNum + channelCallCfg.getCallIndex();
        header.setTraceNo(channelSeqNum);
        header.setTransTime(DateUtil.getCurrentTime());
        header.setTransDate(DateUtil.getCurrentDate());
        aliCreateMerchantRequest.setHeader(header);
        aliCreateMerchantRequest.setMchntName(mchntBaseInfo.getMchntName());
        //商户MCC
        aliCreateMerchantRequest.setMchntType(mchntBaseInfo.getIndustryType());
        aliCreateMerchantRequest.setMchntAbbr(mchntBaseInfo.getMchntSimpleName());
        aliCreateMerchantRequest.setAlipayCategory(alipayMchntInfo.getAlipayCategory());
        //客服电话
        aliCreateMerchantRequest.setServicePhone(mchntBaseInfo.getMchntContactPhone());
        aliCreateMerchantRequest.setChannelId(channelCallCfg.getCallChannelId());
        aliCreateMerchantRequest.setChannelType(alipayMchntInfo.getDstChannelType());

        //联系人信息
        ContactInfo contactInfo = new ContactInfo();
        contactInfo.setContact(mchntSignInfo.getArtifName());
        contactInfo.setContactTelephone(mchntSignInfo.getArtifMobile());
        contactInfo.setContactPhone(mchntSignInfo.getArtifMobile());
        contactInfo.setContactEmail(mchntSignInfo.getArtifEmail());
        contactInfo.setContactJobType("06");
        contactInfo.setContactType("LEGAL_PERSON");
        contactInfo.setCertId(mchntSignInfo.getArtifCertNo());
        aliCreateMerchantRequest.setContactInfoList(Collections.singletonList(contactInfo));

        //地址信息
        AddressInfo addressInfo = new AddressInfo();
        addressInfo.setCityCode(mchntSignInfo.getRegisterCity());
        addressInfo.setDistrictCode(mchntSignInfo.getRegisterArea());
        addressInfo.setAddress(mchntBaseInfo.getMchntBizAddr());
        addressInfo.setProvinceCode(mchntSignInfo.getRegisterProvince());
        aliCreateMerchantRequest.setAddressInfoList(Collections.singletonList(addressInfo));

        List<BankCardInfo> bankCardInfoList = new ArrayList<>();
        mchntAcctInfoList.forEach(item -> convertBankCardInfo(item, bankCardInfoList));
        aliCreateMerchantRequest.setBankCardInfoList(bankCardInfoList);
        return aliCreateMerchantRequest;
    }

    /**
     * 将数据库表结构对象转换成接口对象
     *
     * @param mchntAcctInfo    数据库表结构对象
     * @param bankCardInfoList 接口对象
     */
    private void convertBankCardInfo(MchntAcctInfo mchntAcctInfo, List<BankCardInfo> bankCardInfoList) {
        if (BompAppParamConstant.FLAG_Y.equals(mchntAcctInfo.getRecordStatus())) {
            BankCardInfo bankCardInfo = new BankCardInfo();
            bankCardInfo.setAcctNo(mchntAcctInfo.getSettleAcctNo());
            bankCardInfo.setAcctName(mchntAcctInfo.getSettleAcctName());
            bankCardInfo.setBankName(mchntAcctInfo.getAcctOpenBankName());
            bankCardInfoList.add(bankCardInfo);
        }
    }
}
